1 /* 2 * Copyright (C) 2008 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.collect; 18 19 import static com.google.common.base.Preconditions.checkNotNull; 20 21 import com.google.common.annotations.Beta; 22 import com.google.common.annotations.GwtCompatible; 23 import com.google.common.base.Function; 24 import com.google.common.base.Joiner; 25 import com.google.common.base.Optional; 26 import com.google.common.base.Predicate; 27 28 import java.util.Arrays; 29 import java.util.Collection; 30 import java.util.Comparator; 31 import java.util.Iterator; 32 import java.util.List; 33 import java.util.SortedSet; 34 35 import javax.annotation.CheckReturnValue; 36 import javax.annotation.Nullable; 37 38 /** 39 * {@code FluentIterable} provides a rich interface for manipulating {@code Iterable} instances in a 40 * chained fashion. A {@code FluentIterable} can be created from an {@code Iterable}, or from a set 41 * of elements. The following types of methods are provided on {@code FluentIterable}: 42 * <ul> 43 * <li>chained methods which return a new {@code FluentIterable} based in some way on the contents 44 * of the current one (for example {@link #transform}) 45 * <li>conversion methods which copy the {@code FluentIterable}'s contents into a new collection or 46 * array (for example {@link #toList}) 47 * <li>element extraction methods which facilitate the retrieval of certain elements (for example 48 * {@link #last}) 49 * <li>query methods which answer questions about the {@code FluentIterable}'s contents (for example 50 * {@link #anyMatch}) 51 * </ul> 52 * 53 * <p>Here is an example that merges the lists returned by two separate database calls, transforms 54 * it by invoking {@code toString()} on each element, and returns the first 10 elements as an 55 * {@code ImmutableList}: <pre> {@code 56 * 57 * FluentIterable 58 * .from(database.getClientList()) 59 * .filter(activeInLastMonth()) 60 * .transform(Functions.toStringFunction()) 61 * .limit(10) 62 * .toList();}</pre> 63 * 64 * <p>Anything which can be done using {@code FluentIterable} could be done in a different fashion 65 * (often with {@link Iterables}), however the use of {@code FluentIterable} makes many sets of 66 * operations significantly more concise. 67 * 68 * @author Marcin Mikosik 69 * @since 12.0 70 */ 71 @GwtCompatible(emulated = true) 72 public abstract class FluentIterable<E> implements Iterable<E> { 73 // We store 'iterable' and use it instead of 'this' to allow Iterables to perform instanceof 74 // checks on the _original_ iterable when FluentIterable.from is used. 75 private final Iterable<E> iterable; 76 77 /** Constructor for use by subclasses. */ 78 protected FluentIterable() { 79 this.iterable = this; 80 } 81 82 FluentIterable(Iterable<E> iterable) { 83 this.iterable = checkNotNull(iterable); 84 } 85 86 /** 87 * Returns a fluent iterable that wraps {@code iterable}, or {@code iterable} itself if it 88 * is already a {@code FluentIterable}. 89 */ 90 public static <E> FluentIterable<E> from(final Iterable<E> iterable) { 91 return (iterable instanceof FluentIterable) ? (FluentIterable<E>) iterable 92 : new FluentIterable<E>(iterable) { 93 @Override 94 public Iterator<E> iterator() { 95 return iterable.iterator(); 96 } 97 }; 98 } 99 100 /** 101 * Construct a fluent iterable from another fluent iterable. This is obviously never necessary, 102 * but is intended to help call out cases where one migration from {@code Iterable} to 103 * {@code FluentIterable} has obviated the need to explicitly convert to a {@code FluentIterable}. 104 * 105 * @deprecated instances of {@code FluentIterable} don't need to be converted to 106 * {@code FluentIterable} 107 */ 108 @Deprecated 109 public static <E> FluentIterable<E> from(FluentIterable<E> iterable) { 110 return checkNotNull(iterable); 111 } 112 113 /** 114 * Returns a fluent iterable containing {@code elements} in the specified order. 115 * 116 * @since 18.0 117 */ 118 @Beta 119 public static <E> FluentIterable<E> of(E[] elements) { 120 return from(Lists.newArrayList(elements)); 121 } 122 123 /** 124 * Returns a string representation of this fluent iterable, with the format 125 * {@code [e1, e2, ..., en]}. 126 */ 127 @Override 128 public String toString() { 129 return Iterables.toString(iterable); 130 } 131 132 /** 133 * Returns the number of elements in this fluent iterable. 134 */ 135 public final int size() { 136 return Iterables.size(iterable); 137 } 138 139 /** 140 * Returns {@code true} if this fluent iterable contains any object for which 141 * {@code equals(element)} is true. 142 */ 143 public final boolean contains(@Nullable Object element) { 144 return Iterables.contains(iterable, element); 145 } 146 147 /** 148 * Returns a fluent iterable whose {@code Iterator} cycles indefinitely over the elements of 149 * this fluent iterable. 150 * 151 * <p>That iterator supports {@code remove()} if {@code iterable.iterator()} does. After 152 * {@code remove()} is called, subsequent cycles omit the removed element, which is no longer in 153 * this fluent iterable. The iterator's {@code hasNext()} method returns {@code true} until 154 * this fluent iterable is empty. 155 * 156 * <p><b>Warning:</b> Typical uses of the resulting iterator may produce an infinite loop. You 157 * should use an explicit {@code break} or be certain that you will eventually remove all the 158 * elements. 159 */ 160 @CheckReturnValue 161 public final FluentIterable<E> cycle() { 162 return from(Iterables.cycle(iterable)); 163 } 164 165 /** 166 * Returns a fluent iterable whose iterators traverse first the elements of this fluent iterable, 167 * followed by those of {@code other}. The iterators are not polled until necessary. 168 * 169 * <p>The returned iterable's {@code Iterator} supports {@code remove()} when the corresponding 170 * {@code Iterator} supports it. 171 * 172 * @since 18.0 173 */ 174 @Beta 175 @CheckReturnValue 176 public final FluentIterable<E> append(Iterable<? extends E> other) { 177 return from(Iterables.concat(iterable, other)); 178 } 179 180 /** 181 * Returns a fluent iterable whose iterators traverse first the elements of this fluent iterable, 182 * followed by {@code elements}. 183 * 184 * @since 18.0 185 */ 186 @Beta 187 @CheckReturnValue 188 public final FluentIterable<E> append(E... elements) { 189 return from(Iterables.concat(iterable, Arrays.asList(elements))); 190 } 191 192 /** 193 * Returns the elements from this fluent iterable that satisfy a predicate. The 194 * resulting fluent iterable's iterator does not support {@code remove()}. 195 */ 196 @CheckReturnValue 197 public final FluentIterable<E> filter(Predicate<? super E> predicate) { 198 return from(Iterables.filter(iterable, predicate)); 199 } 200 201 /** 202 * Returns {@code true} if any element in this fluent iterable satisfies the predicate. 203 */ 204 public final boolean anyMatch(Predicate<? super E> predicate) { 205 return Iterables.any(iterable, predicate); 206 } 207 208 /** 209 * Returns {@code true} if every element in this fluent iterable satisfies the predicate. 210 * If this fluent iterable is empty, {@code true} is returned. 211 */ 212 public final boolean allMatch(Predicate<? super E> predicate) { 213 return Iterables.all(iterable, predicate); 214 } 215 216 /** 217 * Returns an {@link Optional} containing the first element in this fluent iterable that 218 * satisfies the given predicate, if such an element exists. 219 * 220 * <p><b>Warning:</b> avoid using a {@code predicate} that matches {@code null}. If {@code null} 221 * is matched in this fluent iterable, a {@link NullPointerException} will be thrown. 222 */ 223 public final Optional<E> firstMatch(Predicate<? super E> predicate) { 224 return Iterables.tryFind(iterable, predicate); 225 } 226 227 /** 228 * Returns a fluent iterable that applies {@code function} to each element of this 229 * fluent iterable. 230 * 231 * <p>The returned fluent iterable's iterator supports {@code remove()} if this iterable's 232 * iterator does. After a successful {@code remove()} call, this fluent iterable no longer 233 * contains the corresponding element. 234 */ 235 public final <T> FluentIterable<T> transform(Function<? super E, T> function) { 236 return from(Iterables.transform(iterable, function)); 237 } 238 239 /** 240 * Applies {@code function} to each element of this fluent iterable and returns 241 * a fluent iterable with the concatenated combination of results. {@code function} 242 * returns an Iterable of results. 243 * 244 * <p>The returned fluent iterable's iterator supports {@code remove()} if this 245 * function-returned iterables' iterator does. After a successful {@code remove()} call, 246 * the returned fluent iterable no longer contains the corresponding element. 247 * 248 * @since 13.0 (required {@code Function<E, Iterable<T>>} until 14.0) 249 */ 250 public <T> FluentIterable<T> transformAndConcat( 251 Function<? super E, ? extends Iterable<? extends T>> function) { 252 return from(Iterables.concat(transform(function))); 253 } 254 255 /** 256 * Returns an {@link Optional} containing the first element in this fluent iterable. 257 * If the iterable is empty, {@code Optional.absent()} is returned. 258 * 259 * @throws NullPointerException if the first element is null; if this is a possibility, use 260 * {@code iterator().next()} or {@link Iterables#getFirst} instead. 261 */ 262 public final Optional<E> first() { 263 Iterator<E> iterator = iterable.iterator(); 264 return iterator.hasNext() 265 ? Optional.of(iterator.next()) 266 : Optional.<E>absent(); 267 } 268 269 /** 270 * Returns an {@link Optional} containing the last element in this fluent iterable. 271 * If the iterable is empty, {@code Optional.absent()} is returned. 272 * 273 * @throws NullPointerException if the last element is null; if this is a possibility, use 274 * {@link Iterables#getLast} instead. 275 */ 276 public final Optional<E> last() { 277 // Iterables#getLast was inlined here so we don't have to throw/catch a NSEE 278 279 // TODO(kevinb): Support a concurrently modified collection? 280 if (iterable instanceof List) { 281 List<E> list = (List<E>) iterable; 282 if (list.isEmpty()) { 283 return Optional.absent(); 284 } 285 return Optional.of(list.get(list.size() - 1)); 286 } 287 Iterator<E> iterator = iterable.iterator(); 288 if (!iterator.hasNext()) { 289 return Optional.absent(); 290 } 291 292 /* 293 * TODO(kevinb): consider whether this "optimization" is worthwhile. Users 294 * with SortedSets tend to know they are SortedSets and probably would not 295 * call this method. 296 */ 297 if (iterable instanceof SortedSet) { 298 SortedSet<E> sortedSet = (SortedSet<E>) iterable; 299 return Optional.of(sortedSet.last()); 300 } 301 302 while (true) { 303 E current = iterator.next(); 304 if (!iterator.hasNext()) { 305 return Optional.of(current); 306 } 307 } 308 } 309 310 /** 311 * Returns a view of this fluent iterable that skips its first {@code numberToSkip} 312 * elements. If this fluent iterable contains fewer than {@code numberToSkip} elements, 313 * the returned fluent iterable skips all of its elements. 314 * 315 * <p>Modifications to this fluent iterable before a call to {@code iterator()} are 316 * reflected in the returned fluent iterable. That is, the its iterator skips the first 317 * {@code numberToSkip} elements that exist when the iterator is created, not when {@code skip()} 318 * is called. 319 * 320 * <p>The returned fluent iterable's iterator supports {@code remove()} if the 321 * {@code Iterator} of this fluent iterable supports it. Note that it is <i>not</i> 322 * possible to delete the last skipped element by immediately calling {@code remove()} on the 323 * returned fluent iterable's iterator, as the {@code Iterator} contract states that a call 324 * to {@code * remove()} before a call to {@code next()} will throw an 325 * {@link IllegalStateException}. 326 */ 327 @CheckReturnValue 328 public final FluentIterable<E> skip(int numberToSkip) { 329 return from(Iterables.skip(iterable, numberToSkip)); 330 } 331 332 /** 333 * Creates a fluent iterable with the first {@code size} elements of this 334 * fluent iterable. If this fluent iterable does not contain that many elements, 335 * the returned fluent iterable will have the same behavior as this fluent iterable. 336 * The returned fluent iterable's iterator supports {@code remove()} if this 337 * fluent iterable's iterator does. 338 * 339 * @param size the maximum number of elements in the returned fluent iterable 340 * @throws IllegalArgumentException if {@code size} is negative 341 */ 342 @CheckReturnValue 343 public final FluentIterable<E> limit(int size) { 344 return from(Iterables.limit(iterable, size)); 345 } 346 347 /** 348 * Determines whether this fluent iterable is empty. 349 */ 350 public final boolean isEmpty() { 351 return !iterable.iterator().hasNext(); 352 } 353 354 /** 355 * Returns an {@code ImmutableList} containing all of the elements from this fluent iterable in 356 * proper sequence. 357 * 358 * @since 14.0 (since 12.0 as {@code toImmutableList()}). 359 */ 360 public final ImmutableList<E> toList() { 361 return ImmutableList.copyOf(iterable); 362 } 363 364 /** 365 * Returns an {@code ImmutableList} containing all of the elements from this {@code 366 * FluentIterable} in the order specified by {@code comparator}. To produce an {@code 367 * ImmutableList} sorted by its natural ordering, use {@code toSortedList(Ordering.natural())}. 368 * 369 * @param comparator the function by which to sort list elements 370 * @throws NullPointerException if any element is null 371 * @since 14.0 (since 13.0 as {@code toSortedImmutableList()}). 372 */ 373 public final ImmutableList<E> toSortedList(Comparator<? super E> comparator) { 374 return Ordering.from(comparator).immutableSortedCopy(iterable); 375 } 376 377 /** 378 * Returns an {@code ImmutableSet} containing all of the elements from this fluent iterable with 379 * duplicates removed. 380 * 381 * @since 14.0 (since 12.0 as {@code toImmutableSet()}). 382 */ 383 public final ImmutableSet<E> toSet() { 384 return ImmutableSet.copyOf(iterable); 385 } 386 387 /** 388 * Returns an {@code ImmutableSortedSet} containing all of the elements from this {@code 389 * FluentIterable} in the order specified by {@code comparator}, with duplicates (determined by 390 * {@code comparator.compare(x, y) == 0}) removed. To produce an {@code ImmutableSortedSet} sorted 391 * by its natural ordering, use {@code toSortedSet(Ordering.natural())}. 392 * 393 * @param comparator the function by which to sort set elements 394 * @throws NullPointerException if any element is null 395 * @since 14.0 (since 12.0 as {@code toImmutableSortedSet()}). 396 */ 397 public final ImmutableSortedSet<E> toSortedSet(Comparator<? super E> comparator) { 398 return ImmutableSortedSet.copyOf(comparator, iterable); 399 } 400 401 /** 402 * Returns an immutable map for which the elements of this {@code FluentIterable} are the keys in 403 * the same order, mapped to values by the given function. If this iterable contains duplicate 404 * elements, the returned map will contain each distinct element once in the order it first 405 * appears. 406 * 407 * @throws NullPointerException if any element of this iterable is {@code null}, or if {@code 408 * valueFunction} produces {@code null} for any key 409 * @since 14.0 410 */ 411 public final <V> ImmutableMap<E, V> toMap(Function<? super E, V> valueFunction) { 412 return Maps.toMap(iterable, valueFunction); 413 } 414 415 /** 416 * Creates an index {@code ImmutableListMultimap} that contains the results of applying a 417 * specified function to each item in this {@code FluentIterable} of values. Each element of this 418 * iterable will be stored as a value in the resulting multimap, yielding a multimap with the same 419 * size as this iterable. The key used to store that value in the multimap will be the result of 420 * calling the function on that value. The resulting multimap is created as an immutable snapshot. 421 * In the returned multimap, keys appear in the order they are first encountered, and the values 422 * corresponding to each key appear in the same order as they are encountered. 423 * 424 * @param keyFunction the function used to produce the key for each value 425 * @throws NullPointerException if any of the following cases is true: 426 * <ul> 427 * <li>{@code keyFunction} is null 428 * <li>An element in this fluent iterable is null 429 * <li>{@code keyFunction} returns {@code null} for any element of this iterable 430 * </ul> 431 * @since 14.0 432 */ 433 public final <K> ImmutableListMultimap<K, E> index(Function<? super E, K> keyFunction) { 434 return Multimaps.index(iterable, keyFunction); 435 } 436 437 /** 438 * Returns an immutable map for which the {@link java.util.Map#values} are the elements of this 439 * {@code FluentIterable} in the given order, and each key is the product of invoking a supplied 440 * function on its corresponding value. 441 * 442 * @param keyFunction the function used to produce the key for each value 443 * @throws IllegalArgumentException if {@code keyFunction} produces the same key for more than one 444 * value in this fluent iterable 445 * @throws NullPointerException if any element of this fluent iterable is null, or if 446 * {@code keyFunction} produces {@code null} for any value 447 * @since 14.0 448 */ 449 public final <K> ImmutableMap<K, E> uniqueIndex(Function<? super E, K> keyFunction) { 450 return Maps.uniqueIndex(iterable, keyFunction); 451 } 452 453 /** 454 * Copies all the elements from this fluent iterable to {@code collection}. This is equivalent to 455 * calling {@code Iterables.addAll(collection, this)}. 456 * 457 * @param collection the collection to copy elements to 458 * @return {@code collection}, for convenience 459 * @since 14.0 460 */ 461 public final <C extends Collection<? super E>> C copyInto(C collection) { 462 checkNotNull(collection); 463 if (iterable instanceof Collection) { 464 collection.addAll(Collections2.cast(iterable)); 465 } else { 466 for (E item : iterable) { 467 collection.add(item); 468 } 469 } 470 return collection; 471 } 472 473 /** 474 * Returns a {@link String} containing all of the elements of this fluent iterable joined with 475 * {@code joiner}. 476 * 477 * @since 18.0 478 */ 479 @Beta 480 public final String join(Joiner joiner) { 481 return joiner.join(this); 482 } 483 484 /** 485 * Returns the element at the specified position in this fluent iterable. 486 * 487 * @param position position of the element to return 488 * @return the element at the specified position in this fluent iterable 489 * @throws IndexOutOfBoundsException if {@code position} is negative or greater than or equal to 490 * the size of this fluent iterable 491 */ 492 public final E get(int position) { 493 return Iterables.get(iterable, position); 494 } 495 496 /** 497 * Function that transforms {@code Iterable<E>} into a fluent iterable. 498 */ 499 private static class FromIterableFunction<E> 500 implements Function<Iterable<E>, FluentIterable<E>> { 501 @Override 502 public FluentIterable<E> apply(Iterable<E> fromObject) { 503 return FluentIterable.from(fromObject); 504 } 505 } 506 }